package com.example.android.synchronization;

import java.util.HashMap;
import java.util.List;

import android.app.Dialog;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

import com.example.android.apis.view.CustomOverlay;
import com.example.android.apis.view.Map;
import com.example.android.game.Building;
import com.example.android.game.GameState;
import com.example.android.game.Player;
import com.example.android.gestures.Gesture;
import com.example.android.google.apis.R;
import com.example.android.network.Client;
import com.example.android.network.OutPacketType;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;

public class Updater implements Runnable {
	private static Updater instance = new Updater();

	private Map map;
	private MapView mapView;
	private HashMap<String, CustomOverlay> playerOverlays = new HashMap<String, CustomOverlay>();
	//private HashMap<Integer, Integer> buildingOverlayIdxs = new HashMap<Integer, Integer>();

	private Client client = Client.getInstance();
	private GameState gameState = GameState.getInstance();

	ThreadEvent resultReady = new ThreadEvent();

	public void onMyLocationChanged(GeoPoint location) {
		gameState.getMainPlayer().setGeoPoint(location);
		int latitudeE6 = location.getLatitudeE6();
		int longitudeE6 = location.getLongitudeE6();
		client.send(OutPacketType.MyLocationChanged, latitudeE6, longitudeE6);
	}

	public void onLogin(String login) {
		gameState.Initialize(login);
		client.send(OutPacketType.Dummy, new Object[] {});// works better ;p
		client.send(OutPacketType.Login, login);
	}

	public void onGesturePerformed(Gesture gesture) {
		Player target;
		HashMap<String, Player> opponents = gameState.getOpponents();
		if (opponents.isEmpty()) {
			target = gameState.getMainPlayer();
		} else {
			target = opponents.values().iterator().next();
		}
		client.send(OutPacketType.GesturePerformed, gesture, target.getLogin());
	}

	public void onBuildingConstructed(int buildingType, GeoPoint location) {
		int buildingId = gameState.getNextBuildingId();
		gameState.getBuildings().put(buildingId,
				new Building(buildingId, location, buildingType));
		int latitudeE6 = location.getLatitudeE6();
		int longitudeE6 = location.getLongitudeE6();
		client.send(OutPacketType.BuildingConstructed, buildingId, latitudeE6,
				longitudeE6, buildingType);
	}

	public void statistics(String login, final int currentHitPoints,
			final int maxHitPoints) {
		final TextView healthTextView = (TextView) map
				.findViewById(R.id.healthTextView);

		String mainLogin = gameState.getMainPlayer().getLogin();
		if (!mainLogin.equals(login)) {
			gameState.getOpponents().get(login).setHp(currentHitPoints);
		} else {

			map.runOnUiThread(new Runnable() {
				@Override
				public void run() {

					if (currentHitPoints <= 0) {

						healthTextView.setText(map
								.getString(R.string.health_text) + " 0");

						
						final Dialog dialog = new Dialog(map); // !!!
						dialog.setContentView(R.layout.dead_dialog);
						dialog.setTitle("Dear player...");

						TextView text = (TextView) dialog
								.findViewById(R.id.dialog_text);
						text.setText("You are defeated!");

						Button dialogButton = (Button) dialog
								.findViewById(R.id.dialogButtonOK);
						
						
						dialogButton.setOnClickListener(new OnClickListener() {
							@Override
							public void onClick(View v) {
								dialog.dismiss();
							}
						});
						dialog.show();

					} else {
						healthTextView.setText(map
								.getString(R.string.health_text)
								+ " "
								+ currentHitPoints + "/" + maxHitPoints);
					}
				}
			});
		}
	}

	public void updatePlayerLocation(final String login, final GeoPoint location) {
		Player player = gameState.getOpponents().get(login);
		player.setGeoPoint(location);
		final CustomOverlay outDatedOverlay = playerOverlays.get(login);

		map.runOnUiThread(new Runnable() {

			@Override
			public void run() {
				List<Overlay> overlays = mapView.getOverlays();
				overlays.remove(outDatedOverlay);
				CustomOverlay newOverlay = new CustomOverlay(location,
						R.drawable.location16);
				playerOverlays.put(login, newOverlay);
				overlays.add(newOverlay);
			}
		});

	}

	public void removePlayer(String login) {
		gameState.getOpponents().remove(login);
		final CustomOverlay playerOverlay = playerOverlays.get(login);
		map.runOnUiThread(new Runnable() {

			@Override
			public void run() {
				List<Overlay> overlays = mapView.getOverlays();
				overlays.remove(playerOverlay);
			}
		});
	}

	public void addPlayer(final Player player) {
		gameState.getOpponents().put(player.getLogin(), player);
		map.runOnUiThread(new Runnable() {

			@Override
			public void run() {
				List<Overlay> overlays = mapView.getOverlays();
				CustomOverlay newOverlay = new CustomOverlay(player
						.getGeoPoint(), R.drawable.location16);
				playerOverlays.put(player.getLogin(), newOverlay);
				overlays.add(newOverlay);
			}
		});

	}

	public void setMapView(MapView mapView) {
		this.mapView = mapView;
	}

	private Updater() {

		new Thread(instance).start();
	}

	public static Updater getInstance() {
		return instance;
	}

	public void init(MapView mapView) {
		this.mapView = mapView;
	}

	public void update(Object object) {
		// TODO update game
	}

	@Override
	public void run() {
		resultReady.await();
	}

	public void setMap(Map map) {
		this.map = map;
	}

}
